package com.codeprophecy.client.doc;

import com.google.gwt.accounts.client.User;
import com.google.gwt.core.client.GWT;
import com.google.gwt.gdata.client.GDataRequestParameters;
import com.google.gwt.gdata.client.GoogleService;
import com.google.gwt.gdata.client.impl.CallErrorException;
import com.google.gwt.user.client.rpc.AsyncCallback;

/**
 * Google Documents service.
 */
public class DocumentsService extends GoogleService {

	private static final DocumentsServiceProxyAsync serviceProxy = GWT
			.create(DocumentsServiceProxy.class);
	private static final String DOCS_SCOPE = "https://docs.google.com/feeds/";

	/**
	 * Constructs a DocumentsService object.
	 * 
	 * @param applicationName
	 *            Name of application (used for tracking).
	 * @return A DocumentsService object.
	 */
	public static native void newInstance(ServiceCallback callback) /*-{
		var onSuccess = callback.@com.codeprophecy.client.doc.ServiceCallback::onSuccess(Lcom/codeprophecy/client/doc/DocumentsService;);
		var onFailure = callback.@com.codeprophecy.client.doc.ServiceCallback::onFailure(Lcom/google/gwt/core/client/JavaScriptObject;);

		var log = function(s){
		        $doc.getElementById('logger').appendChild($doc.createTextNode(s+"\n"));
		}
		
	    var showOnly = function(a){
	        var ids= ['approval','waiting','loading','main','error'];
	        var elem;
	        for(var i=0;i<ids.length;++i){
	                elem = $doc.getElementById(ids[i]);
	                if(elem){
	                        if(ids[i]==a){
	                                elem.style.display = "block";
	                                log("showing "+a);                               
	                        }else{
	                                elem.style.display = "none";
	                        }
	                }
	        }
	        log("over display : "+a)
	    } 		
		
            var login = function(service){
                      log("check: loggin start")
                      var url = 'http://docs.google.com/feeds/documents/private/full';
                    var callback = function(response){
                        if(response.oauthApprovalUrl){
                                log("check 4 : oauth request token");
                                var popup = $wnd.shindig.oauth.popup({
                                destination: response.oauthApprovalUrl,
                                windowOptions: 'height=600,width=800',
                                onOpen: function() {
                                  showOnly("waiting");
                                },
                                onClose: function() {
                                  login(service);  
                                  log("close")                      
                                  showOnly("loading");
                                }
                              });
                              $doc.getElementById('personalize').onclick = popup.createOpenerOnClick();
                              $doc.getElementById('approvalLink').onclick = popup.createApprovedOnClick();
                              showOnly("approval");                 
                        }
                        else if(response.feed){
                                log("authorized");
                                showOnly("main");
                                onSuccess(service, response.feed)    
                        }else{                        
                                log("error: "+response.toString())
                                showOnly("error");
                                onFailure(response);
                        }
                    }
            service.getFeed(url,callback,callback);                
        }     
		           
		     var service = new google.gdata.client.GoogleService('writely','gappr1');
		     service.useOAuth('google');  
		     login(service);
	}-*/;

	protected DocumentsService() {
	}

	/**
	 * Deletes a $doc entry.
	 * 
	 * @param uri
	 *            URI of entry.
	 * @param callback
	 *            Callback defining success and failure handlers for this
	 *            command.
	 */
	public final void deleteDocumentEntry(String uri,
			DocumentEntryCallback callback, GDataRequestParameters parameters) {
		this.deleteEntry(uri, callback, parameters);
	}

	/**
	 * Retrieves a $doc entry.
	 * 
	 * @param uri
	 *            URI of entry.
	 * @param callback
	 *            Callback defining success and failure handlers for this
	 *            command.
	 */
	public final void getDocumentEntry(String uri,
			DocumentEntryCallback callback) {
		this
				.getEntry(uri, callback, DocumentEntry.getConstructor(), true,
						null);
	}

	/**
	 * Retrieves a $doc entry.
	 * 
	 * @param uri
	 *            URI of entry.
	 * @param callback
	 *            Callback defining success and failure handlers for this
	 *            command.
	 * @param parameters
	 *            The request parameters.
	 */
	public final void getDocumentEntry(String uri,
			DocumentEntryCallback callback, GDataRequestParameters parameters) {
		this.getEntry(uri, callback, DocumentEntry.getConstructor(), true,
				parameters);
	}

	/**
	 * Retrieves the feed of documents.
	 * 
	 * @param uri
	 *            URI of feed or query.
	 * @param callback
	 *            Callback defining success and failure handlers for this
	 *            command.
	 */
	public final void getDocumentFeed(String uri, DocumentFeedCallback callback) {
		this.getFeed(uri, callback, DocumentFeed.getConstructor(), true, null);
	}

	/**
	 * Retrieves the feed of documents.
	 * 
	 * @param uri
	 *            URI of feed or query.
	 * @param callback
	 *            Callback defining success and failure handlers for this
	 *            command.
	 * @param parameters
	 *            The request parameters.
	 */
	public final void getDocumentFeed(String uri,
			DocumentFeedCallback callback, GDataRequestParameters parameters) {
		this.getFeed(uri, callback, DocumentFeed.getConstructor(), true,
				parameters);
	}

	/**
	 * Inserts a new $doc entry.
	 * 
	 * @param uri
	 *            URI of feed.
	 * @param entry
	 *            Entry to insert.
	 * @param callback
	 *            Callback defining success and failure handlers for this
	 *            command.
	 */
	public final void insertDocumentEntry(String uri, DocumentEntry entry,
			DocumentEntryCallback callback) {
		this.insertEntry(uri, entry, callback, DocumentEntry.getConstructor());
	}

	/**
	 * Updates a $doc entry.
	 * 
	 * @param uri
	 *            URI of entry.
	 * @param entry
	 *            Entry to update.
	 * @param callback
	 *            Callback defining success and failure handlers for this
	 *            command.
	 */
	public final void updateDocumentEntry(String uri, DocumentEntry entry,
			DocumentEntryCallback callback) {
		this.updateEntry(uri, entry, callback, DocumentEntry.getConstructor(),
				null);
	}

	/**
	 * Updates a $doc entry.
	 * 
	 * @param uri
	 *            URI of entry.
	 * @param entry
	 *            Entry to update.
	 * @param callback
	 *            Callback defining success and failure handlers for this
	 *            command.
	 * @param parameters
	 *            The request parameters.
	 */
	public final void updateDocumentEntry(String uri, DocumentEntry entry,
			DocumentEntryCallback callback, GDataRequestParameters parameters) {
		this.updateEntry(uri, entry, callback, DocumentEntry.getConstructor(),
				parameters);
	}

	/**
	 * Retrieves a $doc's contents.
	 * 
	 * @param documentId
	 *            The $doc id.
	 * @param callback
	 *            Callback defining success and failure handlers for this
	 *            command.
	 */
	public final void getDocumentContents(String documentId,
			final DocumentContentsCallback callback) {
		getDocumentContents(documentId, callback, null);
	}

	/**
	 * Retrieves a $doc's contents.
	 * 
	 * @param documentId
	 *            The $doc id.
	 * @param callback
	 *            Callback defining success and failure handlers for this
	 *            command.
	 * @param parameters
	 *            The request parameters.
	 */
	public final void getDocumentContents(String documentId,
			final DocumentContentsCallback callback,
			GDataRequestParameters parameters) {
		String token = User.checkLogin(DOCS_SCOPE);
		serviceProxy.getDocumentContents("gwt-gdata-ext", token, documentId,
				new AsyncCallback<String>() {
					public void onFailure(Throwable caught) {
						callback.onFailure(new CallErrorException(caught
								.getMessage()));
					}

					public void onSuccess(String result) {
						DocumentContents contents = DocumentContents
								.newInstance();
						contents.setText(result);
						contents.setType("text");
						callback.onSuccess(contents);
					}
				});
	}

	/**
	 * Sets the $doc's contents.
	 * 
	 * @param documentId
	 *            The $doc id.
	 * @param contents
	 *            The $doc contents.
	 * @param callback
	 *            Callback defining success and failure handlers for this
	 *            command.
	 */
	public final void setDocumentContents(String documentId,
			final String contents, final DocumentContentsCallback callback) {
		setDocumentContents(documentId, contents, callback, null);
	}

	/**
	 * Sets the $doc's contents.
	 * 
	 * @param documentId
	 *            The document id.
	 * @param contents
	 *            The document contents.
	 * @param callback
	 *            Callback defining success and failure handlers for this
	 *            command.
	 * @param parameters
	 *            The request parameters.
	 */
	public final void setDocumentContents(String documentId,
			final String contents, final DocumentContentsCallback callback,
			GDataRequestParameters parameters) {
		String token = User.checkLogin(DOCS_SCOPE);
		String etag = null;
		if (parameters != null) {
			etag = parameters.getEtag();
		}
		serviceProxy.setDocumentContents("gwt-gdata-ext", token, documentId,
				etag, contents, new AsyncCallback<Boolean>() {
					public void onFailure(Throwable caught) {
						callback.onFailure(new CallErrorException(caught
								.getMessage()));
					}

					public void onSuccess(Boolean result) {
						DocumentContents dc = DocumentContents.newInstance();
						dc.setText(contents);
						dc.setType("text");
						callback.onSuccess(dc);
					}
				});
	}

}
